﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GDIExtension.Components;

namespace Patchworker
{
	public partial class SpritePanel : ASimpleButton
	{
		int currentFrame = 0;

		Size size;

		ERepeatType repeatType;
		int numFrames = 1;
		bool isPlaying = false;

		bool reversed = false;

		private Rectangle clipRect = new Rectangle();
		private Rectangle renderRect = new Rectangle();
		private Rectangle mouseRect = new Rectangle();

		private Rectangle pRenderRect = new Rectangle();

		private Pen mousePen;

		Timer animationTimer;

		public event EventHandler Redraw;


		public SpritePanel()
		{
			animationTimer = new Timer();
			animationTimer.Tick += AnimationTimer_Tick;

			mousePen = new Pen(Color.Black, 2);
			mousePen.DashStyle= System.Drawing.Drawing2D.DashStyle.Dot;

			this.OnButtonStateChanged += new EventHandler<ButtonStateEventArgs>(SpritePanel_OnButtonStateChanged);
		}
		public Point PointToScreen(Point point)
		{
			return new Point((int)this.X + point.X, (int)this.Y + point.Y);
		}

		public Size Size
		{
			get
			{
				return this.size;
			}
			set
			{
				if (this.size != value)
				{
					this.size = value;
					refreshHitArea();
				}
			}
		}

		public void refreshHitArea()
		{
			if (this.HitArea != null) this.HitArea.Reset();
			else this.HitArea = new System.Drawing.Drawing2D.GraphicsPath();

			this.HitArea.AddRectangle(new Rectangle((int)this.X, (int)this.Y, this.Width, this.Height));
			updateBoundingRect();
		}

		public int Width
		{
			get
			{
				return size.Width;
			}
		}

		public int Height
		{
			get
			{
				return size.Height;

			}
		}

		public override void setPosition(float x, float y)
		{
			base.setPosition(x, y);

			this.renderRect.X = (int)this.X;
			this.renderRect.Y = (int)this.Y;
			redraw();
		}

		public void refresh()
		{
			this.numFrames = ConfigContainer.Instance.NumImageFrames;
			this.Size = ConfigContainer.Instance.TileSize;

			this.clipRect.Width = this.Width;
			this.clipRect.Height = this.Height;
			this.renderRect.Width = this.Width;
			this.renderRect.Height = this.Height;

			mouseRect.Width = this.Width - 1;
			mouseRect.Height = this.Height - 1;
		}


		public override void render(Graphics g)
		{
			if (ConfigContainer.Instance.ImageLoaded)
			{
				this.clipRect.X = (currentFrame % ConfigContainer.Instance.NumHorizontalGrids) * this.clipRect.Width;
				this.clipRect.Y = (currentFrame / ConfigContainer.Instance.NumHorizontalGrids) * this.clipRect.Height;

				this.mouseRect.X = renderRect.X;
				this.mouseRect.Y = renderRect.Y;


				g.DrawImage(ConfigContainer.Instance.Atlas, renderRect, clipRect, GraphicsUnit.Pixel);

				switch(currentButtonState)
				{
					case EButtonState.OVER:
					case EButtonState.DOWN:
						g.DrawRectangle(Pens.White, mouseRect);
						g.DrawRectangle(mousePen, mouseRect);
 						break;
				}
			}
		}



		void SpritePanel_OnButtonStateChanged(object sender, ButtonStateEventArgs e)
		{
			redraw();
		}


		public Rectangle DisplayRectangle(int inflate)
		{
			Rectangle result = Rectangle.Inflate(Rectangle.Union(renderRect, pRenderRect), inflate, inflate);

			pRenderRect = renderRect;

			return result;
			
		}


		public int CurrentFrame
		{
			get
			{
				return currentFrame;
			}
			set
			{
				if (currentFrame != value)
				{
					currentFrame = value % numFrames;
				}
			}
		}

		public ERepeatType RepeatType
		{
			set
			{
				this.repeatType = value;

				switch (repeatType)
				{
					case ERepeatType.Reverse:

						reversed = true;
						break;

					case ERepeatType.Normal:
						reversed = false;
						break;
				}
			}
		}

		public int Interval
		{
			set
			{
				this.animationTimer.Interval = value;
			}
		}


		public bool IsPlaying
		{
			get
			{
				return isPlaying;
			}
			set
			{
				if (value == true)
				{
					animationTimer.Enabled = true;
				}
				else
				{
					animationTimer.Enabled = false;
				}

				this.isPlaying = value;
			}
		}

		private void AnimationTimer_Tick(object sender, EventArgs e)
		{

			//last frame was the final frame
			if (currentFrame == numFrames - 1)
			{
				switch (repeatType)
				{
					case ERepeatType.Once:
						IsPlaying = false;
						break;
					case ERepeatType.PingPong:
						reversed = true;
						break;
				}

			}

			if (currentFrame == 0)
			{
				if (repeatType == ERepeatType.PingPong)
				{
					reversed = false;
				}
			}


			if (reversed == false)
			{
				currentFrame = (currentFrame + 1) % numFrames;
			}
			else
			{
				currentFrame--;
				if (currentFrame < 0) currentFrame = numFrames - 1;
			}

			redraw();
			
		}
		
		public new void redraw()
		{
			//System.Diagnostics.Debug.WriteLine(DateTime.Now);
			if (Redraw != null)
			{
				Redraw(this, new EventArgs());
			}
		}
	}
}
